package com.example.communitysystem.service;

import com.example.communitysystem.dto.CommentDTO;
import com.example.communitysystem.enums.CommentTypeEnum;
import com.example.communitysystem.enums.NotificationStatusEnum;
import com.example.communitysystem.enums.NotificationTypeEnum;
import com.example.communitysystem.exception.CustomizeErrorCode;
import com.example.communitysystem.exception.CustomizeException;
import com.example.communitysystem.mapper.CommentMapper;
import com.example.communitysystem.mapper.NotificationMapper;
import com.example.communitysystem.mapper.QuestionMapper;
import com.example.communitysystem.mapper.UserMapper;
import com.example.communitysystem.model.Comment;
import com.example.communitysystem.model.Notification;
import com.example.communitysystem.model.Question;
import com.example.communitysystem.model.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentService {

    private CommentMapper commentMapper;

    private QuestionMapper questionMapper;

    private UserMapper userMapper;

    private NotificationMapper notificationMapper;

    //添加问题评论信息
    @Transactional
    public void insert(Comment comment,User user){
        //评论不存在，则返回错误信息
        if(comment.getParentId() == null || comment.getParentId() == 0){
            throw new CustomizeException(CustomizeErrorCode.TARGET_PARAM_NOT_FOUND);
        }

        if(comment.getType() == null || !CommentTypeEnum.isExist(comment.getType())){
            throw new CustomizeException(CustomizeErrorCode.TYPE_PARAM_ERROR);
        }

        if(comment.getType() == CommentTypeEnum.COMMENT.getType()){
            //回复的评论
            Comment dbComment = commentMapper.findById(comment.getParentId());
            if(dbComment == null){
                throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FOUND);
            }
            //回复问题
            Question question = questionMapper.getQuestionById(dbComment.getParentId());
            if(question == null){
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
            //添加评论
            commentMapper.insertComment(comment);
            comment.setCommentCount(1);
            //更新评论数
            commentMapper.updateCommentCount(comment.getParentId(), comment.getCommentCount());

            //添加通知信息
            createNotify(comment, dbComment.getCommentator(), user.getLoginName(),question.getTitle(), question.getId(), NotificationTypeEnum.REPLY_COMMENT);
        }else{
            //回复问题
            Question question = questionMapper.getQuestionById(comment.getParentId());
            if(question == null){
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
            //添加回复
            commentMapper.insertComment(comment);
            question.setCommentCount(1);
            //更新回复数
            questionMapper.updateQuestionCommentCount(question.getId(),question.getCommentCount());
            //添加通知信息
            createNotify(comment,question.getCreatorId(),user.getLoginName(), question.getTitle(), question.getId(), NotificationTypeEnum.REPLY_QUESTION);
        }
    }

    //添加通知信息
    private void createNotify(Comment comment, Long receiverId,String notifierName, String title, Long outerId,NotificationTypeEnum notificationTypeEnum) {
        Notification notification = new Notification();
        notification.setGmtCreate(System.currentTimeMillis());
        notification.setType(notificationTypeEnum.getType());
        notification.setOuterId(outerId);
        notification.setNotifierId(comment.getCommentator());
        notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
        notification.setReceiverId(receiverId);
        notification.setNotifierName(notifierName);
        notification.setOuterTitle(title);
        //添加通知信息
        notificationMapper.insertNotification(notification);
    }

    //获取指定id的全部评论,
    // 传入问题id，和一级评论类型则查找指定问题id的全部一级评论
    //传入一级评论id，和二级评论类型则查找指定一级评论id的全部二级评论
    public List<CommentDTO> getCommentDTOListByTargetId(Long id, Integer type){
        //通过父类问题Id和type查找评论信息集合
        List<Comment> commentList = commentMapper.findByParentIdAndType(id,type);
        if(commentList.size() == 0 || commentList == null){
            return new ArrayList<>();
        }
        //从查找的评论集合中获取用户id
        Set<Long> userIdSet = new HashSet<>();
        for(Comment comment : commentList){
            if(!userIdSet.contains(comment.getCommentator())){
                userIdSet.add(comment.getCommentator());
            }
        }
        //通过userIdSet中的用户id获取用户信息集合
        List<User> userList = new ArrayList<>();
        for(Long userId : userIdSet){
            User user;
            user = userMapper.findById(userId);
            if(user != null){
                userList.add(user);
            }
        }
        //把userList转换成map
        Map<Long,User> userMap = userList.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));

        List<CommentDTO> commentDTOList = commentList.stream().map(comment -> {
            CommentDTO commentDTO = new CommentDTO();
            BeanUtils.copyProperties(comment,commentDTO);
            commentDTO.setUser(userMap.get(comment.getCommentator()));
            return commentDTO;
        }).collect(Collectors.toList());

        return commentDTOList;
    }

    @Autowired
    public void setCommentMapper(CommentMapper commentMapper) {
        this.commentMapper = commentMapper;
    }

    @Autowired
    public void setQuestionMapper(QuestionMapper questionMapper) {
        this.questionMapper = questionMapper;
    }

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Autowired
    public void setNotificationMapper(NotificationMapper notificationMapper) {
        this.notificationMapper = notificationMapper;
    }
}
